<?php

namespace app\controller\admin;

use app\BaseController;
use app\model\Account;
use app\model\BalanceNotice;
use app\model\ProductAttr;
use app\model\Store;
use app\model\User;
use app\model\UserScoreRecharge;
use think\facade\Cache;
use think\response\Json;

class Home extends BaseController
{
    public function product(): Json
    {
        $attr_stock = $this->app->make(ProductAttr::class)->where('state', '<>', 3)->order("price")->select()->toArray();
        //获取最近10天的使用量
        $endDate = date("Y-m-d 23:59:59", strtotime("-1 day"));
        $startDate = date("Y-m-d 00:00:00", strtotime("-9 days", strtotime($endDate)));
        $order = $this->app->make(\app\model\Order::class)->where('create_time', '>', $startDate)->where('create_time', '<', $endDate)->whereIn('state', [1, 2])->field("attr_id,count(attr_id) total")->group("attr_id")->select()->toArray();
        $order = array_column($order, null, 'attr_id');
        $attr_stock = array_map(function ($item) use ($order) {
            if (isset($order[$item['id']])) {
                $avg = bcdiv($order[$item['id']]['total'], 10, 2);
                $item['avg'] = $avg;
                $item['day'] = bcdiv($item['stock'], $avg, 2);
            } else {
                $item['avg'] = 0;
                $item['day'] = $item['stock'];
            }
            return $item;
        }, $attr_stock);
        $sum = array_sum(array_column($attr_stock, 'stock'));
        $attr_stock[] = ["name" => "合计", "stock" => $sum];

        return $this->success(compact("attr_stock"));
    }

    public function repetRechargeMobile()
    {
        $endDate = date("Y-m-d 23:59:59", strtotime("-1 day"));
        $startDate = date("Y-m-d 00:00:00", strtotime("-59 days", strtotime($endDate)));
        $order = $this->app->make(UserScoreRecharge::class)->with(['store', 'account'])->where('create_time', 'between', [$startDate, $endDate])->where('state', 1)->where('pid', '<>', 5)->where('uid', '<>', 15)->group("uid")->having('count(uid) > 3')->field("uid,count(uid) total,sum(number) number,aid,sid")->paginate(['list_rows' => 15, 'page' => $this->request->param("page", 1)])->toArray();
        $uid = array_column($order['data'], 'uid');
        if (!empty($uid)) {
            $account = $this->app->make(User::class)->whereIn('id', $uid)->column("mobile", "id");
            $order['data'] = array_map(function ($item) use ($account) {
                $item['mobile'] = $account[$item['uid']];
                $item['number'] = (float)bcdiv($item['number'], 100, 2);
                return $item;
            }, $order['data']);
        }
        return $this->success($order);
    }

    public function rechargeStoreToFive(): Json
    {
        $timer = date("Y-m-d 00:00:00", strtotime("-6 day"));
        //获取最近5天充值的门店
        $reModel = $this->app->make(UserScoreRecharge::class);
        $recharge = $reModel->where('create_time', '>', $timer)->where('sid', '<>', 13)->column("sid");
        $recharge[] = 13;
        $stores = $this->app->make(Store::class)->whereNotIn('id', $recharge)->where('is_del', 1)->where('state', 1)->select()->toArray();
        if (!empty($stores)) {
            $stores = array_map(function ($item) use ($reModel) {
                $item['last_create_time'] = $reModel->where('sid', $item['id'])->order("create_time", "desc")->value("create_time");
                return $item;
            }, $stores);
        }
        return $this->success(compact("stores"));
    }

    public function moneyStatic(): Json
    {
        $rechargeMoney = $this->app->make(BalanceNotice::class)->where('supplier_id', '<>', 5)->select()->toArray();
        $money = 0;
        if (!empty($rechargeMoney)) {
            foreach ($rechargeMoney as $v) {
                if ($v['type'] == 1) $money += $v['number'];
                else $money -= $v['number'];
            }
        }
        $money = (float)bcdiv($money, 100, 2);
        //获取剩余采购油卡库存
        $price = $this->app->make(ProductAttr::class)->where("state", '<>', 3)->value("sum(price * stock) price");
        //获取已销售油卡
        $order_money = $this->app->make(\app\model\Order::class)->whereIn("state", [1, 2])->value("sum(price) price");
        $price = (float)bcadd($price, bcdiv($order_money, 100, 2), 2);
        $sale_price = (float)bcsub($money, $price, 2);
        $changeMoney = $this->app->make(User::class)->where('balance', '>', 0)->where('mobile', '<>', '13281112344')->sum("balance");
        $changeMoney = (float)($changeMoney != 0 ? bcdiv($changeMoney, 100, 2) : 0);
        $fuhaiMoney = $this->app->make(User::class)->where(['mobile' => '13281112344'])->value("balance");
        $fuhaiMoney = (float)($fuhaiMoney != 0 ? bcdiv($fuhaiMoney, 100, 2) : 0);
        $supplierModel = $this->app->make(Account::class);
        $supplier = $supplierModel->where(['type' => 3, 'is_del' => 1])->where('supplier_id', '<>', 5)->sum("balance");
        $store_balance = $supplierModel->where(['type' => 2, 'is_del' => 1])->where('supplier_id', '<>', 5)->group('store_id')->field("balance")->select()->toArray();
        $balance = array_sum(array_column($store_balance, 'balance'));
        $balance = (float)($balance != 0 ? bcdiv($balance, 100, 2) : 0);
        $supplier = (float)($supplier != 0 ? bcdiv($supplier, 100, 2) : 0);
        $supplier = (float)bcadd($supplier, $balance, 2);
        $changes = $this->app->make(UserScoreRecharge::class);
        $totalRecharge = $changes->where('state', 1)->where('pid', '<>', 5)->sum('number');
        $totalRecharge = (float)($totalRecharge > 0 ? bcdiv($totalRecharge, 100, 2) : 0);
        $fuhaiRecharge = $changes->when(true, function ($query) {
            $query->whereIn('uid', User::where('mobile', '13281112344')->column("id"));
        })->where('state', 1)->sum('number');
        $fuhaiRecharge = (float)($fuhaiRecharge != 0 ? bcdiv($fuhaiRecharge, 100, 2) : 0);
        return $this->success(compact("money", "price", "sale_price", "changeMoney", "fuhaiMoney", 'supplier', 'totalRecharge', 'fuhaiRecharge'));
    }

    //获取最近30天兑换油卡数量
    public function exchangeOilCardNumber(): Json
    {
        $endDate = date("Y-m-d 23:59:59", strtotime("-1 day"));
        $startDate = date("Y-m-d 00:00:00", strtotime("-29 days", strtotime($endDate)));

        // 生成30天的日期标签
        $key = [];
        for ($i = 30; $i >= 1; $i--) {
            $key[] = date("j日", strtotime("-$i day", strtotime(date("Y-m-d"))));
        }

        // 获取订单统计数据
        //按照日期、金额分组
        $orderData = $this->app->make(\app\model\Order::class)
            ->where('create_time', 'between', [$startDate, $endDate])
            ->whereIn('state', [1, 2])
            ->order('create_time')
            ->group('attr_id,DATE(create_time)')
            ->field('attr_id,DATE(create_time) create_time,count(attr_id) amount,sum(price) money')
            ->select()->toArray();
        //获取油卡规格
        $attr = $this->app->make(ProductAttr::class)->order("price")->column("name", "id");
        // 获取积分划拨记录
        $changeData = $this->app->make(UserScoreRecharge::class)
            ->where('create_time', 'between', [$startDate, $endDate])
            ->where('pid', '<>', 5)
            ->order('create_time')
            ->where("uid", 15)
            ->where('state', 1)
            ->group('uid,DATE(create_time)')
            ->field('DATE(create_time) create_time,sum(number) price')
            ->select()->toArray();
        // 初始化数据数组
        $scoreNumber = array_fill_keys($key, 0);
        $fuhaiNumber = array_fill_keys($key, 0);
        $orderNumber = array_map(function ($item) use ($key) {
            return [
                "name" => $item,
                "data" => array_fill_keys($key, 0),
                "type" => "line",
                "smooth" => true
            ];
        }, $attr);
        // 处理订单数据
        if (!empty($orderData)) {
            foreach ($orderData as $order) {
                $date = date("j日", strtotime($order['create_time']));
                $attr_id = $order['attr_id'];
                if (isset($orderNumber[$attr_id])) {
                    $orderNumber[$attr_id]['data'][$date] = (float)bcadd($orderNumber[$date] ?? 0, $order['amount'], 2);
                }
                $scoreNumber[$date] = (float)bcadd($scoreNumber[$date] ?? 0, bcdiv($order['money'], 100, 2), 2);
            }
        }
        $orderNumber = array_values($orderNumber);
        $orderNumber = array_map(function ($item) {
            $item['data'] = array_values($item['data']);
            return $item;
        }, $orderNumber);
        $orderlegend = array_column($orderNumber, 'name');
        // 处理积分划拨数据
        if (!empty($changeData)) {
            foreach ($changeData as $change) {
                $date = date("j日", strtotime($change['create_time']));
                $amount = bcdiv($change['price'], 100, 2);
                // 判断是否为富海回收 (通过手机号判断而不是硬编码ID)
                $fuhaiNumber[$date] = (float)bcadd($fuhaiNumber[$date] ?? 0, $amount, 2);
            }
        }
        $scoreLst = [
            ["name" => "兑换量", "data" => array_values($scoreNumber), "type" => "line", "smooth" => true],
            ["name" => "回收量", "data" => array_values($fuhaiNumber), "type" => "line", "smooth" => true],
        ];
        return $this->success(compact("orderNumber", "scoreLst", "key", "orderlegend"));
    }

    public function exchangeChats(): Json
    {
        //获取油卡规格
        $attr = $this->app->make(ProductAttr::class)->order("price")->column("name", "id");
        $orderData = $this->app->make(\app\model\Order::class)
            ->whereIn('state', [1, 2])
            ->order('price')
            ->group('attr_id,state')
            ->column('attr_id,count(attr_id) stock,sum(price) money,state');
        $product = $this->app->make(ProductAttr::class)->order('face_value')->column("id,(face_value * stock) money,stock", "id");
        $items = [];
        foreach ($orderData as $value) {
            $name = $attr[$value['attr_id']] ?? "未知";
            $money = (float)bcdiv($value['money'], 100, 2);
            $key = $value['state'] == 1 ? "dis_" : "use_";
            if (!isset($items[$value['attr_id']]['name'])) {
                $items[$value['attr_id']]['name'] = "中石油{$name}加油券";
                $items[$value['attr_id']]["sys_stock"] = $product[$value['attr_id']]['stock'];
                $items[$value['attr_id']]["sys_money"] = $product[$value['attr_id']]['money'];
            }
            $items[$value['attr_id']][$key . "money"] = $money;
            $items[$value['attr_id']][$key . "stock"] = $value['stock'];
        }
        $items[99] = [
            "name" => "合计",
            "sys_stock" => array_sum(array_column($items, "sys_stock")),
            "sys_money" => array_sum(array_column($items, "sys_money")),
            "dis_money" => array_sum(array_column($items, "dis_money")),
            "dis_stock" => array_sum(array_column($items, "dis_stock")),
            "use_money" => array_sum(array_column($items, "use_money")),
            "use_stock" => array_sum(array_column($items, "use_stock")),
        ];
        return $this->success(array_values($items));
    }

    public function oilProductRecharge(): Json
    {
        //最近半年积分销售统计
        $key = [];
//        $m = (int)date("m");
        $s = 5;
        $e = 0;
        if ((int)date("d") == 1) {
            $e = 1;
            $s = 6;
        }
        for ($i = $s; $i >= $e; $i--) {
            $time = strtotime(date("Y-m-01"));
            $key[] = date("m月", strtotime("-$i month", $time));
        }
        $endDate = date("Y-m-d 23:59:59", strtotime("-1 day"));
        $startDate = date("Y-m-01 00:00:00", strtotime("-$s month", strtotime(date("Y-m-01"))));
        //获取充值数据
        $recharge = $this->app->make(BalanceNotice::class)->where("supplier_id", '<>', 5)->where('create_time', 'between', [$startDate, $endDate])->group('DATE(create_time),type')->order("create_time,type")->column("sum(number) number,DATE(create_time) date,type");
        $data = [
            ['name' => "门店充值", 'data' => array_fill_keys($key, 0), 'type' => 'bar', "smooth" => true, "label" => ['show' => true, 'position' => 'top']],
            ['name' => '门店划拨', 'data' => array_fill_keys($key, 0), 'type' => 'bar', 'smooth' => true, "label" => ['show' => true, 'position' => 'top']],
            ['name' => '富海回收', 'data' => array_fill_keys($key, 0), 'type' => 'bar', 'smooth' => true, "label" => ['show' => true, 'position' => 'top']],
            ['name' => '回收占比', 'data' => array_fill_keys($key, 0), 'type' => 'line', 'smooth' => true, "yAxisIndex" => 1, "label" => ['show' => true, 'position' => 'top']]
        ];
        foreach ($recharge as $item) {
            $month = date("m月", strtotime($item['date']));
            $number = (float)bcdiv($item['number'], 100, 2);
            $type = $item['type'] == 1 ? 0 : 1;
            if ($type == 0) {
                $data[0]['data'][$month] = (float)bcadd($data[0]['data'][$month] ?? 0, $number, 2);
            } else {
                $data[0]['data'][$month] = (float)bcsub($data[0]['data'][$month] ?? 0, $number, 2);
            }
        }

        $changeData = $this->app->make(UserScoreRecharge::class)
            ->where('create_time', 'between', [$startDate, $endDate])
            ->where('pid', '<>', 5)
            ->order('create_time')
            ->where('state', 1)
            ->group('uid,DATE(create_time)')
            ->field('DATE(create_time) create_time,sum(number) price,uid')
            ->select()->toArray();
        foreach ($changeData as $change) {
            $month = date("m月", strtotime($change['create_time']));
            $price = (float)bcdiv($change['price'], 100, 2);
            $data[1]['data'][$month] = (float)bcadd($price, $data[1]['data'][$month] ?? 0, 2);
//            dd($data);
            if ($change['uid'] == 15) {
                $data[2]['data'][$month] = (float)bcadd($price, $data[2]['data'][$month] ?? 0, 2);
            }

            if (isset($data[2]['data'][$month]) && $data[2]['data'][$month] > 0) {
                $data[3]['data'][$month] = (float)bcmul(bcdiv($data[2]['data'][$month], $data[1]['data'][$month], 4), 100, 2);
            }
        }

        $data[0]['data'] = array_values($data[0]['data']);
        $data[1]['data'] = array_values($data[1]['data']);
        $data[2]['data'] = array_values($data[2]['data']);
        $data[3]['data'] = array_values($data[3]['data']);
        $lend = array_column($data, "name");
        return $this->success(compact("data", "key", "lend"));
    }

    /**
     * 计算油卡积分回收数据
     *
     * @param int $type 类型：1-按日统计，2-按月统计
     * @param string $cacheKey 缓存键
     * @param string $startDate 开始日期
     * @param string $endDate 结束日期
     * @return array
     */
    private function calculateOilRecyclingData($type, &$startDate, &$endDate): array
    {
        // 根据类型设置时间范围和缓存键
        if ($type == 2) {
            // 按月统计，最近6个月
            $endDate = date("Y-m-d 23:59:59", strtotime("-1 day", strtotime(date("Y-m-01"))));
            $start = strtotime("-1 month", strtotime(date("Y-m-01")));
            $startDate = date("Y-m-01 00:00:00", strtotime("-5 month", $start));
            //生成最近6月的日期标签
            $key = [];
            for ($i = 5; $i >= 0; $i--) {
                $key[] = date("n月", strtotime("-$i month", $start));
            }
        } else {
            // 按日统计，最近30天
            $endDate = date("Y-m-d 23:59:59", strtotime("-1 day"));
            $startDate = date("Y-m-d 00:00:00", strtotime("-29 days", strtotime($endDate)));
            $key = []; // 日统计时$key会在后面赋值
        }
        // 计算总发放数量（排除富海内部账号）
        $orderModel = new UserScoreRecharge();
        $orders = $orderModel->with(['store' => function ($query) {
            $query->field("id,name");
        }])
            ->where('state', 1)
            ->where('pid', '<>', 5)
            ->where('create_time', 'between', [$startDate, $endDate])
            ->group('sid,DATE(create_time),uid')
            ->order('sid')
            ->field('sid,DATE(create_time) create_time,uid,sum(number) number')
//            ->cache($cacheKey, strtotime(date("Y-m-t 23:59:59")))
            ->select()->toArray();
        // 处理数据
        $stores = [];
        $items = [];
        $fuhaiUserId = 15; // 富海用户ID

        foreach ($orders as $order) {
            $storeId = $order['sid'];
            $userId = $order['uid'];
            $number = $order['number'];

            $stores[$storeId] = $order['store']['name'];

            if ($type == 1) {
                // 按门店汇总（日统计）
                $items[$storeId]['recycle'] = isset($items[$storeId]['recycle']) ?
                    bcadd($items[$storeId]['recycle'], $number) : $number;

                if ($userId == $fuhaiUserId) {
                    $items[$storeId]['fuhai'] = isset($items[$storeId]['fuhai']) ?
                        bcadd($items[$storeId]['fuhai'], $number) : $number;
                }

                if (isset($items[$storeId]['fuhai'])) {
                    $items[$storeId]['rates'] = bcmul(bcdiv($items[$storeId]['fuhai'], $items[$storeId]['recycle'], 4), 100, 2);
                }
            } else {
                // 按门店和月份分别统计（月统计）
                $month = date("n月", strtotime($order['create_time']));
                $items[$storeId][$month]['recycle'] = isset($items[$storeId][$month]['recycle']) ?
                    bcadd($items[$storeId][$month]['recycle'], $number) : $number;

                if ($userId == $fuhaiUserId) {
                    $items[$storeId][$month]['fuhai'] = isset($items[$storeId][$month]['fuhai']) ?
                        bcadd($items[$storeId][$month]['fuhai'], $number) : $number;
                }

                if (isset($items[$storeId][$month]['fuhai'])) {
                    $items[$storeId][$month]['rates'] = bcmul(bcdiv($items[$storeId][$month]['fuhai'], $items[$storeId][$month]['recycle'], 4), 100, 2);
                }
            }
        }
        // 格式化结果数据
        if ($type == 1) {
            $key = array_values($stores);
            $res = [['name' => "数据占比", "data" => array_values(array_column($items, "rates")), "type" => "bar", "label" => ['show' => true, 'position' => 'top', 'format' => '%']]];
        } else {
            $res = array_fill_keys(
                array_keys($stores),
                ["name" => "数据占比", "data" => array_fill_keys($key, 0), "type" => "line", "smooth" => true, "label" => ['show' => true, 'position' => 'top', 'format' => '%']]
            );

            foreach ($items as $storeId => $monthlyData) {
                foreach ($monthlyData as $month => $data) {
                    $res[$storeId]['data'][$month] = $data['rates'];
                }
                $res[$storeId]['data'] = array_values($res[$storeId]['data']);
            }

            $res = array_values($res);
        }

        $stores = array_values($stores);
        return compact("res", "key", "stores");
    }

    public function exchangeOilRecycle(): Json
    {
//        Cache::clear();
        $type = $this->request->param("type", 1);
        $cacheKey = "4s_oil_recy_helf_{$type}_new";
//        if((int)date("d") ==){}
//        if (!Cache::has($cacheKey . "_data") || (int)date("d") === 1) {
            $data = $this->calculateOilRecyclingData($type, $startDate, $endDate);
            //缓存到月底
//            Cache::set($cacheKey . "_data", $data, strtotime(date("Y-m-t 23:59:59")));
//        } else {
//            $data = Cache::get($cacheKey . "_data");
//        }
        return $this->success($data);
    }

    public function storeRecharge(): Json
    {
        $param = $this->request->param();
        $recharge = $this->app->make(BalanceNotice::class);
        //获取内测账号
        $store = $this->app->make(Store::class)->where('pid', 5)->column('id');
        $total = $recharge->with(["store"])->where("create_time", ">=", date("Y-m-d 00:00:00", strtotime("-6 month")))->whereNotIn("store_id", $store)->group("store_id")->field("store_id,sum(number) number")->order("store_id")->paginate(['list_rows' => 15, "page" => $param['page']])->toArray();
        $total['data'] = array_map(function ($v) use ($recharge) {
            //最近半年内的充值情况
            $start = $recharge->where("store_id", $v['store_id'])->where("create_time", ">=", date("Y-m-d 00:00:00", strtotime("-6 month")))->order("create_time")->column("create_time");
            //计算两个日期之间的差值
            $days = [];
            for ($i = 0; $i < count($start) - 1; $i++) {
                $s = new \DateTime($start[$i]);
                $e = new \DateTime($start[$i + 1]);
                $days[] = $e->diff($s)->days;
            }
            $v['total'] = count($start);
            $v['last_time'] = end($start);
            $today = new \DateTime(date("Y-m-d 23:59:59"));
            $today = $today->diff(new \DateTime($v['last_time']))->days;
            $v['day'] = (float)bcdiv(array_sum($days), $v['total'], 2);
            if($v['day'] > 0){
                $v['today'] = $v['day'] > 0 ? (float)bcsub($today, $v['day']) : 0;
            } else {
                $v['day'] = "--";
                $v['today'] = $today > 5 ? $today : 0;
            }
            //计算
            $v['number'] = (float)bcdiv($v['number'], 100, 2);
            return $v;
        }, $total['data']);
        return $this->success($total);
    }
}
